package cn.wolfcode.shop.web.frontend;

import cn.wolfcode.shop.common.Result;
import cn.wolfcode.shop.domain.OrderInfo;
import cn.wolfcode.shop.domain.SeckillOrder;
import cn.wolfcode.shop.domain.User;
import cn.wolfcode.shop.mq.MQConstants;
import cn.wolfcode.shop.mq.OrderMessage;
import cn.wolfcode.shop.redis.RedisTemplate;
import cn.wolfcode.shop.redis.SeckillServerKeyPrefix;
import cn.wolfcode.shop.service.IOrderInfoService;
import cn.wolfcode.shop.service.ISeckillGoodService;
import cn.wolfcode.shop.vo.SeckillGoodVo;
import cn.wolfcode.shop.web.result.SeckillServerCodeMsg;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;

@RestController
@RequestMapping("order")
public class OrderInfoController {

    @Autowired
    private ISeckillGoodService seckillGoodService;

    @Autowired
    private IOrderInfoService orderInfoService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public static final ConcurrentHashMap<Long, Boolean> STOCK_OVER_SIGN = new ConcurrentHashMap<>();

    // QPS: 每秒钟能处理的请求数
    // 优化前 QPS: 500 * 10 的情况下 qps=120
    // 优化后 第一次测试 QPS: 500 * 10 的情况下 qps=172
    // 优化后 第二次测试 QPS: 500 * 10 的情况下 qps=223
    @RequestMapping("/{path}/seckill")
    public Result<Boolean> seckill(String uuid,Long seckillGoodId, User user,@PathVariable("path") String path){
        String oldPath = redisTemplate.get(SeckillServerKeyPrefix.SECKILL_PATH, uuid, String.class);
        if (StringUtils.isEmpty(oldPath) || !oldPath.equals(path)){
            return Result.error(SeckillServerCodeMsg.SECKILL_ERROR);
        }
        if (user == null){
            return Result.error(SeckillServerCodeMsg.OP_ERROR);
        }
        Boolean isOverSign = STOCK_OVER_SIGN.get(seckillGoodId);
        if (isOverSign != null && isOverSign){
            return Result.error(SeckillServerCodeMsg.SECKILL_OVER);
        }
        SeckillGoodVo vo = seckillGoodService.find(seckillGoodId);
        if (vo == null){
            return Result.error(SeckillServerCodeMsg.OP_ERROR);
        }

        if(vo.getStartDate().getTime() - new Date().getTime()>0){
            return Result.error(SeckillServerCodeMsg.OP_ERROR);
        }
        SeckillOrder seckillOrder = redisTemplate.get(SeckillServerKeyPrefix.SECKILL_ORDER,user.getId()+":"+seckillGoodId, SeckillOrder.class);
        if (seckillOrder != null){
            return Result.error(SeckillServerCodeMsg.SECKILL_REPEAT);
        }
        // 利用redis的原子性递减来控制人数
        Long remainStock = redisTemplate.decr(SeckillServerKeyPrefix.SECKILL_GOOD_STOCK,seckillGoodId+"");
        if (remainStock < 0){
            STOCK_OVER_SIGN.put(seckillGoodId,true);
            return Result.error(SeckillServerCodeMsg.SECKILL_OVER);
        }
      //  String orderNo = orderInfoService.seckill(user.getId(), seckillGoodId);
        OrderMessage orderMessage = new OrderMessage(user.getId(),seckillGoodId,uuid);
        rabbitTemplate.convertAndSend("", MQConstants.ORDER_PEDDING_QUEUE,orderMessage);
        return Result.success(true);
    }

    @RequestMapping("find")
    public Result<OrderInfo> find(String orderNo, User user){
        if (user == null){
            return Result.error(SeckillServerCodeMsg.OP_ERROR);
        }
        OrderInfo orderInfo = orderInfoService.find(orderNo);
        if (orderInfo == null || !orderInfo.getUserId().equals(user.getId())){
            return Result.error(SeckillServerCodeMsg.OP_ERROR);
        }
        return Result.success(orderInfo);
    }

}
